

package org.example.service;

import com.alibaba.fastjson.JSONObject;
import org.example.entity.LogTimes;
import org.example.entity.OperateLog;
import org.example.entity.Response;
import org.example.entity.TimeDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.SimpleFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author ：jiangyaru
 * @date ：2024/4/6 23:03
 */
@Component
public class LogService {

    public static SimpleDateFormat sdfHM = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    public static  SimpleDateFormat sdfH = new SimpleDateFormat("yyyy-MM-dd HH");
    public Response readLog(String filename, String sTime, String eTime, MultipartFile file) throws IOException {
        Response result = new Response();
        // 转化为字节数组
        byte[] data = file.getBytes();
        // 使用UTF-8编码将字节数组转换为字符串
        String content = new String(data, StandardCharsets.UTF_8);
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String regular = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(regular);
        Matcher matcher = pa.matcher(content);
        List<OperateLog> logs = new ArrayList<>();
        while (matcher.find()) {
            // 转化为json对象
            OperateLog operateLog = JSONObject.parseObject(matcher.group(), OperateLog.class);
            logs.add(operateLog);
            System.out.println(matcher.group());
        }
        return result;
    }

    public static void main(String[] args) {
        String ss = "地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:49\",\"method\":\"Response dt.hn.client.demo.web.HNDataQueryController.GetStation5minData(String,String,String)\",\"operateIp\":\"10.169.153.42\",\"operateParam\":\"  startTime: 2024-04-07 01:00:00  endTime: 2024-04-07 16:00:00  siteId: 106\",\"operateUrl\":\"/hnjczx/dataquery/findStation5minData\",\"requestMethod\":\"GET\",\"respTime\":63,\"resultKB\":124.189453125,\"startTime\":\"2024-04-07 15:16:49\",\"status\":0,\"title\":\"获取多站点所有因子5min数据\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-363] [dt.hn.client.demo.config.TokenHandler] [INFO] - 62acae02-2ff5-46bc-8fa5-7a8832a31baa2024-04-07 15:16:49结束请求/hnjczx/dataquery/findStation5minData\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.config.TokenHandler] [INFO] - 61725f17-e879-4038-94c5-7de0d8f09c402024-04-07 15:16:51 进入请求: /hnjczx/AlarmOperation/GetAlarmInfos\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.loginfo.LogAspect] [INFO] - /hnjczx/AlarmOperation/GetAlarmInfos 地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:52\",\"method\":\"Response dt.hn.client.demo.web.AlarmOperationController.GetAlarmInfos(String,String,String,String,Integer,Integer,Integer,String,String,String,String)\",\"operateIp\":\"10.170.95.2\",\"operateParam\":\"  officeIns: 4107  userid: 20230601205716582100C0470C7BCD84  A_StartTime: 2024-04-07 00:00:00  B_EndTime: 2024-04-07 15:16:57  C_AlarmType: 1  D_AlarmState: 1  E_AlarmLevel: null  siteID: null  AlarmTitle: null  AlarmTitleID: null  AlarmDes: null\",\"operateUrl\":\"/hnjczx/AlarmOperation/GetAlarmInfos\",\"requestMethod\":\"GET\",\"respTime\":218,\"resultKB\":0.0400390625,\"startTime\":\"2024-04-07 15:16:51\",\"status\":0,\"title\":\"获取报警信息\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.config.TokenHandler] [INFO] - 61725f17-e879-4038-94c5-7de0d8f09c402024-04-07 15:16:52结束请求/hnjczx/AlarmOperation/GetAlarmInfos\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.config.TokenHandler] [INFO] - b320e94e-8229-4ced-b3e1-364e1e70122f2024-04-07 15:16:53 进入请求: /hnjczx/dataquery/GetDataSeriesSite\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.loginfo.LogAspect] [INFO] - /hnjczx/dataquery/GetDataSeriesSite 地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:54\",\"method\":\"Response dt.hn.client.demo.web.HNDataQueryController.GetDataSeriesSite(String,String,String,String,String)\",\"operateIp\":\"10.41.100.115\",\"operateParam\":\"  siteid: 211,212  timetype: 01  starttime: 2024-03-31 01:00:00  endtime: 2024-04-07 23:00:00  itemid: 101,102\",\"operateUrl\":\"/hnjczx/dataquery/GetDataSeriesSite\",\"requestMethod\":\"GET\",\"respTime\":313,\"resultKB\":33.515625,\"startTime\":\"2024-04-07 15:16:53\",\"status\":0,\"title\":\"查询站点时序数据\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.config.TokenHandler] [INFO] - b320e94e-8229-4ced-b3e1-364e1e70122f2024-04-07 15:16:54结束请求/hnjczx/dataquery/GetDataSeriesSite";
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String vv = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(vv);
        Matcher matcher = pa.matcher(ss);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

    public Response queryPortHourTimes(String sTime, String eTime, MultipartFile file) throws IOException, ParseException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logs = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logs)) {
            result.msg = "没有数据";
            return result;
        }

        for (OperateLog log : logs) {
            log.setTimeHour(sdfH.parse(log.getStartTime()));
            log.setTimeMinutes(sdfHM.parse(log.getStartTime()));
        }
        // 过滤出查询时间段的日志
        List<OperateLog> logss = logs.stream().filter(s -> {
            try {
                return sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(sTime)) >= 0
                        && sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(eTime)) <= 0;
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logss.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<Date, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            // detailTimes 按照时间 排序
            detailTimes.sort(Comparator.comparing(TimeDetails::getTime));
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;
    }
    public Response queryOnePortTimes(String sTime, String eTime,String portName, MultipartFile file) throws IOException, ParseException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logsAll = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logsAll)) {
            result.msg = "没有数据";
            return result;
        }
        for (OperateLog log : logsAll) {
            log.setTimeHour(sdfH.parse(log.getStartTime()));
            log.setTimeMinutes(sdfHM.parse(log.getStartTime()));
        }
        List<OperateLog> logs = new ArrayList<>();
        if (!StringUtils.isEmpty(portName)) {
            List<String> names = Arrays.asList(portName.split(","));
            logs = logsAll.stream().filter(s -> names.contains(s.getOperateUrl())).collect(Collectors.toList());
        }else {
            logs = logsAll;
        }

        // 过滤出查询时间段的日志
        List<OperateLog> logss = logs.stream().filter(s -> {
            try {
                return sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(sTime)) >= 0
                        && sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(eTime)) <= 0;
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());

        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logss.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<Date, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;

    }

    public Response queryOnePortTimesByUser(String sTime, String eTime, String ip, MultipartFile file) throws IOException, ParseException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logsAll = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logsAll)) {
            result.msg = "没有数据";
            return result;
        }
        for (OperateLog log : logsAll) {
            log.setTimeHour(sdfH.parse(log.getStartTime()));
            log.setTimeMinutes(sdfHM.parse(log.getStartTime()));
        }
        List<OperateLog> logs = logsAll.stream().filter(s -> ip.equals(s.getOperateIp())).collect(Collectors.toList());


        // 过滤出查询时间段的日志
        List<OperateLog> logss = logs.stream().filter(s -> {
            try {
                return sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(sTime)) >= 0
                        && sdfHM.parse(s.getStartTime()).compareTo(sdfHM.parse(eTime)) <= 0;
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logss.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<Date, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;
    }

    private List<OperateLog> generateLogJSON(MultipartFile file) throws IOException {
        List<OperateLog> logs = new ArrayList<>();
        // 转化为字节数组
        byte[] data = file.getBytes();
        // 使用UTF-8编码将字节数组转换为字符串
        String content = new String(data, StandardCharsets.UTF_8);
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String regular = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(regular);
        Matcher matcher = pa.matcher(content);
        int i = 0;
        while (matcher.find()) {
            // 转化为json对象
            try {
                OperateLog operateLog = JSONObject.parseObject(matcher.group(), OperateLog.class);
                logs.add(operateLog);
//                System.out.println(matcher.group());
            }catch (Exception e) {
                e.printStackTrace();
                i = i+1;
                System.out.println(i);
                System.out.println(matcher.group());
            }

        }
        return logs;
    }


}


/*
package org.example.service;

import com.alibaba.fastjson.JSONObject;
import org.example.entity.LogTimes;
import org.example.entity.OperateLog;
import org.example.entity.Response;
import org.example.entity.TimeDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

*/
/**
 * @author ：jiangyaru
 * @date ：2024/4/6 23:03
 *//*

@Component
public class LogService {
    public Response readLog(String filename, String sTime, String eTime, MultipartFile file) throws IOException {
        Response result = new Response();
        // 转化为字节数组
        byte[] data = file.getBytes();
        // 使用UTF-8编码将字节数组转换为字符串
        String content = new String(data, StandardCharsets.UTF_8);
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String regular = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(regular);
        Matcher matcher = pa.matcher(content);
        List<OperateLog> logs = new ArrayList<>();
        while (matcher.find()) {
            // 转化为json对象
            OperateLog operateLog = JSONObject.parseObject(matcher.group(), OperateLog.class);
            logs.add(operateLog);
            System.out.println(matcher.group());
        }
        return result;
    }

    public static void main(String[] args) {
        String ss = "地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:49\",\"method\":\"Response dt.hn.client.demo.web.HNDataQueryController.GetStation5minData(String,String,String)\",\"operateIp\":\"10.169.153.42\",\"operateParam\":\"  startTime: 2024-04-07 01:00:00  endTime: 2024-04-07 16:00:00  siteId: 106\",\"operateUrl\":\"/hnjczx/dataquery/findStation5minData\",\"requestMethod\":\"GET\",\"respTime\":63,\"resultKB\":124.189453125,\"startTime\":\"2024-04-07 15:16:49\",\"status\":0,\"title\":\"获取多站点所有因子5min数据\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-363] [dt.hn.client.demo.config.TokenHandler] [INFO] - 62acae02-2ff5-46bc-8fa5-7a8832a31baa2024-04-07 15:16:49结束请求/hnjczx/dataquery/findStation5minData\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.config.TokenHandler] [INFO] - 61725f17-e879-4038-94c5-7de0d8f09c402024-04-07 15:16:51 进入请求: /hnjczx/AlarmOperation/GetAlarmInfos\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.loginfo.LogAspect] [INFO] - /hnjczx/AlarmOperation/GetAlarmInfos 地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:52\",\"method\":\"Response dt.hn.client.demo.web.AlarmOperationController.GetAlarmInfos(String,String,String,String,Integer,Integer,Integer,String,String,String,String)\",\"operateIp\":\"10.170.95.2\",\"operateParam\":\"  officeIns: 4107  userid: 20230601205716582100C0470C7BCD84  A_StartTime: 2024-04-07 00:00:00  B_EndTime: 2024-04-07 15:16:57  C_AlarmType: 1  D_AlarmState: 1  E_AlarmLevel: null  siteID: null  AlarmTitle: null  AlarmTitleID: null  AlarmDes: null\",\"operateUrl\":\"/hnjczx/AlarmOperation/GetAlarmInfos\",\"requestMethod\":\"GET\",\"respTime\":218,\"resultKB\":0.0400390625,\"startTime\":\"2024-04-07 15:16:51\",\"status\":0,\"title\":\"获取报警信息\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-342] [dt.hn.client.demo.config.TokenHandler] [INFO] - 61725f17-e879-4038-94c5-7de0d8f09c402024-04-07 15:16:52结束请求/hnjczx/AlarmOperation/GetAlarmInfos\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.config.TokenHandler] [INFO] - b320e94e-8229-4ced-b3e1-364e1e70122f2024-04-07 15:16:53 进入请求: /hnjczx/dataquery/GetDataSeriesSite\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.loginfo.LogAspect] [INFO] - /hnjczx/dataquery/GetDataSeriesSite 地址:请求结束：{\"businessType\":0,\"endTime\":\"2024-04-07 15:16:54\",\"method\":\"Response dt.hn.client.demo.web.HNDataQueryController.GetDataSeriesSite(String,String,String,String,String)\",\"operateIp\":\"10.41.100.115\",\"operateParam\":\"  siteid: 211,212  timetype: 01  starttime: 2024-03-31 01:00:00  endtime: 2024-04-07 23:00:00  itemid: 101,102\",\"operateUrl\":\"/hnjczx/dataquery/GetDataSeriesSite\",\"requestMethod\":\"GET\",\"respTime\":313,\"resultKB\":33.515625,\"startTime\":\"2024-04-07 15:16:53\",\"status\":0,\"title\":\"查询站点时序数据\"}结束。\n" +
                "  2024-04-07-15-16 [http-nio-8080-exec-364] [dt.hn.client.demo.config.TokenHandler] [INFO] - b320e94e-8229-4ced-b3e1-364e1e70122f2024-04-07 15:16:54结束请求/hnjczx/dataquery/GetDataSeriesSite";
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String vv = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(vv);
        Matcher matcher = pa.matcher(ss);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

    public Response queryPortHourTimes(String sTime, String eTime, MultipartFile file) throws IOException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logs = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logs)) {
            result.msg = "没有数据";
            return result;
        }
        for (OperateLog log : logs) {
            log.setTimeHour(log.getEndTime().substring(0, 13));
            log.setTimeMinutes(log.getEndTime().substring(0, 16));
        }
        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logs.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<String, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;
    }
    public Response queryOnePortTimes(String sTime, String eTime,String portName, MultipartFile file) throws IOException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logsAll = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logsAll)) {
            result.msg = "没有数据";
            return result;
        }
        for (OperateLog log : logsAll) {
            log.setTimeHour(log.getEndTime().substring(0, 13));
            log.setTimeMinutes(log.getEndTime().substring(0, 16));
        }
        List<OperateLog> logs = new ArrayList<>();
        if (!StringUtils.isEmpty(portName)) {
            List<String> names = Arrays.asList(portName.split(","));
            logs = logsAll.stream().filter(s -> names.contains(s.getOperateUrl())).collect(Collectors.toList());
        }else {
            logs = logsAll;
        }
        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logs.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<String, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;

    }

    public Response queryOnePortTimesByUser(String sTime, String eTime, String ip, MultipartFile file) throws IOException {
        Response result = new Response();
        // 读取文件，生成访问接口详细信息的json对象
        List<OperateLog> logsAll = generateLogJSON(file);
        if (CollectionUtils.isEmpty(logsAll)) {
            result.msg = "没有数据";
            return result;
        }
        for (OperateLog log : logsAll) {
            log.setTimeHour(log.getEndTime().substring(0, 13));
            log.setTimeMinutes(log.getEndTime().substring(0, 16));
        }
        List<OperateLog> logs = logsAll.stream().filter(s -> ip.equals(s.getOperateIp())).collect(Collectors.toList());
        // 接口名称分组
        Map<String, List<OperateLog>> urlMap =
                logs.stream().collect(Collectors.groupingBy(OperateLog::getOperateUrl));
        List<LogTimes> logTimes = new ArrayList<>();
        urlMap.forEach((url, list)-> {
            LogTimes detail = new LogTimes();
            detail.setPortName(url);
            List<TimeDetails> detailTimes = new ArrayList<>();
            // 按照分钟分组
            Map<String, List<OperateLog>> minutesMap = list.stream().collect(Collectors.groupingBy(OperateLog::getTimeMinutes));
            minutesMap.forEach((minutes, lists)-> {
                TimeDetails details = new TimeDetails();
                details.setTime(minutes);
                details.setTimes(lists.size());
                detailTimes.add(details);
            });
            detail.setDetailTimes(detailTimes);
            logTimes.add(detail);
        });
        result.data = logTimes;
        result.msg = "查询成功";
        result.code = 1;
        return result;
    }

    private List<OperateLog> generateLogJSON(MultipartFile file) throws IOException {
        List<OperateLog> logs = new ArrayList<>();
        // 转化为字节数组
        byte[] data = file.getBytes();
        // 使用UTF-8编码将字节数组转换为字符串
        String content = new String(data, StandardCharsets.UTF_8);
        // \\{表示匹配{，{是元字符，要用\转义
        // ()用来指定子表达式。如果是单个字符比如匹配0个或多个A，要用A*，如果这里A也是一个表达式的话要用()括起来，后面再加限定符
        // []中可以直接列出要匹配的字符或数字，[aeiou]匹配元音字母，[0-9]匹配0到9，作用同\d
        // ^}表示匹配 } 以外的字符
        String regular = "\\{([^}])*\\}";
        Pattern pa = Pattern.compile(regular);
        Matcher matcher = pa.matcher(content);
        while (matcher.find()) {
            // 转化为json对象
            OperateLog operateLog = JSONObject.parseObject(matcher.group(), OperateLog.class);
            logs.add(operateLog);
            System.out.println(matcher.group());
        }
        return logs;
    }


}
*/
